import React, { FC, useState, useEffect, useRef } from 'react';
import { Button, message } from 'antd';
import { PictureOutlined, ExpandOutlined } from '@ant-design/icons';
import styles from './index.less';
import { createOutpaintingTask } from '@/services/api';
import { OutpaintingParams } from '@/services/types';

const model = 'image-out-painting';

interface OutpaintingProps {
  imageUrl?: string;
  onClose: () => void;
  onTaskGenerated?: (taskId: string, model: string) => void;
}

// 创建一个比例图标组件
const RatioIcon: React.FC<{ ratio: string }> = ({ ratio }) => {
  if (ratio === 'original') {
    return <PictureOutlined />;
  }

  const [width, height] = ratio.split(':').map(Number);
  const maxSize = 18; // 最大尺寸

  // 计算实际尺寸，保持比例
  let iconWidth = width;
  let iconHeight = height;

  // 等比例缩放，确保最大边不超过 maxSize
  if (width > height) {
    iconWidth = maxSize;
    iconHeight = (height * maxSize) / width;
  } else {
    iconHeight = maxSize;
    iconWidth = (width * maxSize) / height;
  }

  return (
    <div className={styles.ratioIcon}>
      <div style={{ width: `${iconWidth}px`, height: `${iconHeight}px` }} />
    </div>
  );
};

const aspectRatios = [
  { label: '原比例', value: 'original', ratio: 'original' },
  { label: '1:1', value: '1-1', ratio: '1:1' },
  { label: '3:4', value: '3-4', ratio: '3:4' },
  { label: '4:3', value: '4-3', ratio: '4:3' },
  { label: '9:16', value: '9-16', ratio: '9:16' },
  { label: '16:9', value: '16-9', ratio: '16:9' },
];

// 扩图组件
const Outpainting: FC<OutpaintingProps> = ({ imageUrl, onClose, onTaskGenerated }) => {
  const [scale, setScale] = useState(1);
  const [frameSize, setFrameSize] = useState({ width: 0, height: 0 });
  const isDraggingRef = useRef<string | null>(null);
  const imageRef = useRef<HTMLImageElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [selectedRatio, setSelectedRatio] = useState<string>('original');
  const [lastSelectedRatio, setLastSelectedRatio] = useState<string>('original');
  const [originalSize, setOriginalSize] = useState({ width: 0, height: 0 });
  const [isImageLoaded, setIsImageLoaded] = useState(false);
  const [scaledSize, setScaledSize] = useState({ width: 0, height: 0 });
  const [params, setParams] = useState<OutpaintingParams>({
    angle: 0,
    output_ratio: '',
    x_scale: 1.0,
    y_scale: 1.0,
    top_offset: 0,
    bottom_offset: 0,
    left_offset: 0,
    right_offset: 0,
    best_quality: true,
    limit_image_size: true,
    add_watermark: false
  });
  const [isDragging, setIsDragging] = useState(false);

  // 将 props 保存到 ref 中，确保我们总是能访问到最新的值
  const propsRef = useRef({ onTaskGenerated, onClose });

  // 更新 ref
  useEffect(() => {
    propsRef.current = { onTaskGenerated, onClose };
  }, [onTaskGenerated, onClose]);

  // 组件挂载时检查属性
  useEffect(() => {
    console.log('Outpainting 组件挂载，属性检查:', {
      imageUrl: !!imageUrl,
      onClose: !!onClose,
      onTaskGenerated: !!onTaskGenerated,
      onTaskGeneratedType: typeof onTaskGenerated
    });
  }, []);

  // 初始化时设置边框与缩放后的图片大小一致
  useEffect(() => {
    if (imageUrl && containerRef.current) {
      const img = new Image();
      img.onload = () => {
        // 1. 获取容器尺寸
        const containerWidth = containerRef.current?.clientWidth ?? 0;
        const containerHeight = containerRef.current?.clientHeight ?? 0;
        // console.log('容器尺寸:', { containerWidth, containerHeight });

        // 2. 计算目标显示区域（容器的80%）
        const maxWidth = containerWidth * 0.5;
        const maxHeight = containerHeight * 0.5;
        // console.log('可用区域尺寸:', { maxWidth, maxHeight });

        // 3. 记录原始图片尺寸
        console.log('图片原始尺寸:', { width: img.width, height: img.height });

        // 4. 计算缩放比例
        const scaleX = maxWidth / img.width;
        const scaleY = maxHeight / img.height;
        const newScale = Math.min(scaleX, scaleY);
        // console.log('计算得到的缩放比例:', newScale);

        // 5. 计算最终显示尺寸
        const scaledWidth = img.width * newScale;
        const scaledHeight = img.height * newScale;
        // console.log('图片缩放后尺寸:', { scaledWidth, scaledHeight });

        // 6. 更新状态
        setOriginalSize({ width: img.width, height: img.height });
        setScale(newScale);
        setFrameSize({
          width: scaledWidth,
          height: scaledHeight
        });
        setScaledSize({ width: scaledWidth, height: scaledHeight });
        setIsImageLoaded(true);
      };
      img.src = imageUrl;
    }
  }, [imageUrl]);

  // 在渲染时也打印frameSize
  useEffect(() => {
    console.log('当前灰色区域尺寸:', frameSize);
  }, [frameSize]);

  // 拖动灰色区域
  const handleDragStart = (corner: string) => (e: React.MouseEvent) => {
    e.preventDefault();
    isDraggingRef.current = corner;
    setIsDragging(true);
    setLastSelectedRatio(selectedRatio);
    setSelectedRatio('');
    document.addEventListener('mousemove', handleDragMove);
    document.addEventListener('mouseup', handleDragEnd);
  };

  // 鼠标拖动灰色区域
  const handleDragMove = (e: MouseEvent) => {
    if (!isDraggingRef.current || isDraggingRef.current !== 'bottomRight') return;

    // 使用 scaledSize 而不是未定义的 scaledWidth/scaledHeight
    setFrameSize(prev => ({
      width: Math.max(prev.width + e.movementX, scaledSize.width),  // 使用 scaledSize.width
      height: Math.max(prev.height + e.movementY, scaledSize.height) // 使用 scaledSize.height
    }));
  };

  // 鼠标拖动灰色区域结束
  const handleDragEnd = () => {
    isDraggingRef.current = null;
    setIsDragging(false);
    document.removeEventListener('mousemove', handleDragMove);
    document.removeEventListener('mouseup', handleDragEnd);
  };

  // 计算扩图参数
  const calculateOutpaintingParams = (): OutpaintingParams => {
    if (!scaledSize) return params;

    // 计算各个方向的偏移量（像素），需要除以缩放比例得到原图尺寸下的偏移值
    const horizontalOffset = Math.round((frameSize.width - scaledSize.width) / 2 / scale);
    const verticalOffset = Math.round((frameSize.height - scaledSize.height) / 2 / scale);

    // 获取当前选中的比例配置
    const ratioConfig = aspectRatios.find(r => r.value === selectedRatio);

    // 设置 output_ratio：原比例为空字符串，其他使用实际比例
    let outputRatio = '';
    if (ratioConfig && ratioConfig.ratio !== 'original') {
      outputRatio = ratioConfig.ratio;
    }

    return {
      ...params,
      output_ratio: outputRatio,
      x_scale: 1.0,
      y_scale: 1.0,
      left_offset: horizontalOffset,
      right_offset: horizontalOffset,
      top_offset: verticalOffset,
      bottom_offset: verticalOffset,
    };
  };

  // 处理生成按钮点击
  const handleGenerate = async () => {
    if (!imageUrl) {
      message.error('请先上传图片');
      return;
    }

    try {
      const outpaintingParams = calculateOutpaintingParams();
      const task_id = await createOutpaintingTask(imageUrl, outpaintingParams);
      console.log('扩图任务创建成功，task_id:', task_id);

      if (typeof onTaskGenerated === 'function') {
        onTaskGenerated(task_id, model);
      } else {
        console.log('onTaskGenerated 类型:', typeof onTaskGenerated);
      }

      onClose();
    } catch (error) {
      console.error('创建扩图任务失败:', error);
      message.error('创建扩图任务失败');
    }
  };

  const handleRatioChange = (ratio: string) => {
    if (isDragging) return;

    const ratioConfig = aspectRatios.find(r => r.ratio === ratio);
    if (ratioConfig) {
      setSelectedRatio(ratioConfig.value);
    }

    if (ratio === 'original') {
      setFrameSize({
        width: scaledSize.width,
        height: scaledSize.height
      });
      return;
    }

    // 解析目标比例
    const [targetWidth, targetHeight] = ratio.split(':').map(Number);
    const targetRatio = targetWidth / targetHeight;

    // 当前缩放后的尺寸
    const currentWidth = scaledSize.width;
    const currentHeight = scaledSize.height;

    let newWidth, newHeight;

    // 1:1 的情况，以长边为准
    if (targetRatio === 1) {
      const maxSide = Math.max(currentWidth, currentHeight);
      newWidth = maxSide;
      newHeight = maxSide;
    }
    // 宽边比例 > 高度比例的情况 (如 4:3, 16:9)
    else if (targetRatio > 1) {
      newHeight = currentHeight; // 保持高度不变
      newWidth = currentHeight * targetRatio; // 按比例计算宽度
    }
    // 高边比例 > 宽度比例的情况 (如 3:4, 9:16)
    else {
      newWidth = currentWidth; // 保持宽度不变
      newHeight = currentWidth / targetRatio; // 按比例计算高度
    }

    setFrameSize({
      width: newWidth,
      height: newHeight
    });
  };

  return (
    <div className={styles.outpainting}>
      {/* 顶部比例选择区域 */}
      <div className={styles.header}>
        <div className={styles.headerContent}>
          <div className={styles.headerTitle}>
            <ExpandOutlined />
            <h4>扩图</h4>
          </div>
          <div className={styles.ratioButtonsWrapper}>
            <div className={styles.ratioButtons}>
              {aspectRatios.map(ratio => (
                <div
                  key={ratio.value}
                  className={`${styles.ratioButton} 
                    ${selectedRatio === ratio.value ? styles.selected : ''} 
                    ${isDragging ? styles.disabled : ''}`}
                  onClick={() => handleRatioChange(ratio.ratio)}
                  style={{
                    cursor: isDragging ? 'not-allowed' : 'pointer',
                    opacity: isDragging ? 0.5 : 1
                  }}
                >
                  <RatioIcon ratio={ratio.ratio} />
                  <span>{ratio.label}</span>
                </div>
              ))}
            </div>
          </div>
          <Button type="text" onClick={onClose} style={{ fontSize: '14px', fontWeight: '500' }}>
            取消
          </Button>
        </div>
      </div>

      {/* 中间图片编辑区域 */}
      <div className={styles.content} ref={containerRef}>
        <div className={styles.imageContainer}>
          <div
            className={styles.imageWrapper}
            style={{
              visibility: isImageLoaded ? 'visible' : 'hidden'
            }}
          >
            <img
              ref={imageRef}
              src={imageUrl}
              alt="待扩图"
              style={{
                width: `${scaledSize.width}px`,
                height: `${scaledSize.height}px`,
                objectFit: 'contain'
              }}
            />
            <div
              className={styles.expandFrame}
              style={{
                width: `${frameSize.width}px`,
                height: `${frameSize.height}px`,
              }}
            >
              <div
                className={`${styles.corner} ${styles.bottomRight}`}
                onMouseDown={handleDragStart('bottomRight')}
              />
            </div>
          </div>
        </div>
      </div>

      {/* 底部按钮区域 */}
      <div className={styles.footer}>
        <Button
          type="primary"
          onClick={handleGenerate}
          className={styles.generateButton}
        >
          按新尺寸生成图片
        </Button>
      </div>
    </div>
  );
};

export default Outpainting;
